# Justfile for database initialization CI/CD
# Usage: just <command> [args...]
# Variables can be set via environment variables or passed as arguments
#
# Note: This justfile handles:
# - DB Init image build and push
# - DB Init job deployment via Helm

# -----------------------------
# Default variables (can be overridden via environment or command line)
# -----------------------------
DEFAULT_BACKEND_REPO := "https://gitee.com/tjccc/go-pan.git"
DEFAULT_BACKEND_REF := "master"
DEFAULT_WORK_DIR := "./work"

DEFAULT_REGISTRY := "192.168.0.104:5000"
DEFAULT_REGISTRY_NAMESPACE := "library"
DEFAULT_DB_INIT_IMAGE_NAME := "netdisk-db-init"
# Note: IMAGE_TAG defaults to git commit hash if not specified
DEFAULT_IMAGE_TAG := "latest"

DEFAULT_K8S_NAMESPACE := "netdisk"
DEFAULT_RELEASE_DB_INIT := "netdisk-db-init"
DEFAULT_HELM_CHART_DB_INIT := "../../helm/db-init"
DEFAULT_KUBECONFIG_PATH := "~/.kube/config"

# -----------------------------
# Clone: Clone backend repository from Gitee
# -----------------------------
clone BACKEND_REPO='' BACKEND_REF='' WORK_DIR='':
    #!/usr/bin/env bash
    set -e
    
    # Priority: provided args (if not empty) > environment variables > defaults
    if [ -n "$BACKEND_REPO" ]; then
        FINAL_BACKEND_REPO="$BACKEND_REPO"
    else
        FINAL_BACKEND_REPO="${BACKEND_REPO:-{{DEFAULT_BACKEND_REPO}}}"
    fi
    
    if [ -n "$BACKEND_REF" ]; then
        FINAL_BACKEND_REF="$BACKEND_REF"
    else
        FINAL_BACKEND_REF="${BACKEND_REF:-{{DEFAULT_BACKEND_REF}}}"
    fi
    
    if [ -n "$WORK_DIR" ]; then
        FINAL_WORK_DIR="$WORK_DIR"
    else
        FINAL_WORK_DIR="${WORK_DIR:-{{DEFAULT_WORK_DIR}}}"
    fi
    
    echo "Cloning backend repo ${FINAL_BACKEND_REPO}@${FINAL_BACKEND_REF} ..."
    
    # Create work directory first
    mkdir -p "${FINAL_WORK_DIR}"
    
    # Convert to absolute path to avoid issues
    FINAL_WORK_DIR_ABS=$(cd "${FINAL_WORK_DIR}" && pwd)
    REPO_DIR="${FINAL_WORK_DIR_ABS}/go-pan"
    
    # Ensure idempotency: clean before clone
    if [ -d "${REPO_DIR}" ]; then
        echo "Cleaning existing repository: ${REPO_DIR}"
        rm -rf "${REPO_DIR}"
    fi
    
    # Clone repository (fresh clone ensures idempotency)
    git clone --depth 1 --branch "${FINAL_BACKEND_REF}" "${FINAL_BACKEND_REPO}" "${REPO_DIR}"
    
    # Get git commit hash for image tagging
    cd "${REPO_DIR}"
    GIT_COMMIT_HASH=$(git rev-parse --short HEAD)
    GIT_COMMIT_FULL=$(git rev-parse HEAD)
    
    # Save commit info to artifact file
    ARTIFACT_DIR="${FINAL_WORK_DIR_ABS}/.artifacts"
    mkdir -p "${ARTIFACT_DIR}"
    {
        echo "GIT_COMMIT_HASH=${GIT_COMMIT_HASH}"
        echo "GIT_COMMIT_FULL=${GIT_COMMIT_FULL}"
        echo "GIT_BRANCH=${FINAL_BACKEND_REF}"
    } > "${ARTIFACT_DIR}/git-info.env"
    echo "Git commit info saved: ${GIT_COMMIT_HASH} (${GIT_COMMIT_FULL})"
    
    echo "Clone complete: ${REPO_DIR}"

# -----------------------------
# Build: Build Docker image for database initialization
# -----------------------------
build REGISTRY='' REGISTRY_NAMESPACE='' DB_INIT_IMAGE_NAME='' IMAGE_TAG='' WORK_DIR='':
    #!/usr/bin/env bash
    set -e
    
    # Priority: provided args (if not empty) > environment variables > defaults
    if [ -n "$REGISTRY" ]; then
        FINAL_REGISTRY="$REGISTRY"
    else
        FINAL_REGISTRY="${REGISTRY:-{{DEFAULT_REGISTRY}}}"
    fi
    
    if [ -n "$REGISTRY_NAMESPACE" ]; then
        FINAL_REGISTRY_NAMESPACE="$REGISTRY_NAMESPACE"
    else
        FINAL_REGISTRY_NAMESPACE="${REGISTRY_NAMESPACE:-{{DEFAULT_REGISTRY_NAMESPACE}}}"
    fi
    
    if [ -n "$DB_INIT_IMAGE_NAME" ]; then
        FINAL_DB_INIT_IMAGE_NAME="$DB_INIT_IMAGE_NAME"
    else
        FINAL_DB_INIT_IMAGE_NAME="${DB_INIT_IMAGE_NAME:-{{DEFAULT_DB_INIT_IMAGE_NAME}}}"
    fi
    
    if [ -n "$WORK_DIR" ]; then
        FINAL_WORK_DIR="$WORK_DIR"
    else
        FINAL_WORK_DIR="${WORK_DIR:-{{DEFAULT_WORK_DIR}}}"
    fi
    
    # Convert to absolute path
    FINAL_WORK_DIR_ABS=$(cd "${FINAL_WORK_DIR}" && pwd)
    REPO_DIR="${FINAL_WORK_DIR_ABS}/go-pan"
    
    # Check if repository exists
    if [ ! -d "${REPO_DIR}" ]; then
        echo "Error: Repository not found at ${REPO_DIR}"
        echo "Please run 'just clone' first"
        exit 1
    fi
    
    # Load git commit hash from artifact file (if available)
    ARTIFACT_DIR="${FINAL_WORK_DIR_ABS}/.artifacts"
    if [ -f "${ARTIFACT_DIR}/git-info.env" ]; then
        source "${ARTIFACT_DIR}/git-info.env"
        echo "Loaded git commit hash: ${GIT_COMMIT_HASH}"
    else
        # Fallback: get from repo directly
        cd "${REPO_DIR}"
        GIT_COMMIT_HASH=$(git rev-parse --short HEAD)
        echo "Got git commit hash from repo: ${GIT_COMMIT_HASH}"
    fi
    
    # Determine image tag: provided > git commit hash > default
    if [ -n "$IMAGE_TAG" ]; then
        FINAL_IMAGE_TAG="$IMAGE_TAG"
    elif [ -n "${GIT_COMMIT_HASH:-}" ]; then
        FINAL_IMAGE_TAG="${GIT_COMMIT_HASH}"
    else
        FINAL_IMAGE_TAG="{{DEFAULT_IMAGE_TAG}}"
    fi
    
    # Build full image name
    FULL_IMAGE_NAME="${FINAL_REGISTRY}/${FINAL_REGISTRY_NAMESPACE}/${FINAL_DB_INIT_IMAGE_NAME}:${FINAL_IMAGE_TAG}"
    
    echo "Building DB Init image: ${FULL_IMAGE_NAME}"
    echo "Build context: ${REPO_DIR}"
    
    # Build Docker image
    # Note: Build context is repo root because Dockerfile needs COPY db/scheme.sql
    cd "${REPO_DIR}"
    docker build --no-cache -f db/init/Dockerfile -t "${FULL_IMAGE_NAME}" .
    
    # Save image info to artifact file
    mkdir -p "${ARTIFACT_DIR}"
    {
        echo "IMAGE_REGISTRY=${FINAL_REGISTRY}"
        echo "IMAGE_NAMESPACE=${FINAL_REGISTRY_NAMESPACE}"
        echo "IMAGE_NAME=${FINAL_DB_INIT_IMAGE_NAME}"
        echo "IMAGE_TAG=${FINAL_IMAGE_TAG}"
        echo "FULL_IMAGE_NAME=${FULL_IMAGE_NAME}"
    } > "${ARTIFACT_DIR}/image-info.env"
    
    echo "Build complete: ${FULL_IMAGE_NAME}"

# -----------------------------
# Push: Push Docker image to registry
# -----------------------------
push REGISTRY='' REGISTRY_NAMESPACE='' DB_INIT_IMAGE_NAME='' IMAGE_TAG='' WORK_DIR='':
    #!/usr/bin/env bash
    set -e
    
    # Priority: provided args (if not empty) > environment variables > defaults
    if [ -n "$REGISTRY" ]; then
        FINAL_REGISTRY="$REGISTRY"
    else
        FINAL_REGISTRY="${REGISTRY:-{{DEFAULT_REGISTRY}}}"
    fi
    
    if [ -n "$REGISTRY_NAMESPACE" ]; then
        FINAL_REGISTRY_NAMESPACE="$REGISTRY_NAMESPACE"
    else
        FINAL_REGISTRY_NAMESPACE="${REGISTRY_NAMESPACE:-{{DEFAULT_REGISTRY_NAMESPACE}}}"
    fi
    
    if [ -n "$DB_INIT_IMAGE_NAME" ]; then
        FINAL_DB_INIT_IMAGE_NAME="$DB_INIT_IMAGE_NAME"
    else
        FINAL_DB_INIT_IMAGE_NAME="${DB_INIT_IMAGE_NAME:-{{DEFAULT_DB_INIT_IMAGE_NAME}}}"
    fi
    
    if [ -n "$WORK_DIR" ]; then
        FINAL_WORK_DIR="$WORK_DIR"
    else
        FINAL_WORK_DIR="${WORK_DIR:-{{DEFAULT_WORK_DIR}}}"
    fi
    
    # Convert to absolute path
    FINAL_WORK_DIR_ABS=$(cd "${FINAL_WORK_DIR}" && pwd)
    ARTIFACT_DIR="${FINAL_WORK_DIR_ABS}/.artifacts"
    
    # Try to load image info from artifact file (from build)
    if [ -f "${ARTIFACT_DIR}/image-info.env" ]; then
        source "${ARTIFACT_DIR}/image-info.env"
        echo "Loaded image info from artifact file"
        FINAL_IMAGE_TAG="${IMAGE_TAG}"
        FULL_IMAGE_NAME="${FULL_IMAGE_NAME}"
    else
        # Fallback: construct from parameters
        if [ -n "$IMAGE_TAG" ]; then
            FINAL_IMAGE_TAG="$IMAGE_TAG"
        else
            # Try to get from git-info.env
            if [ -f "${ARTIFACT_DIR}/git-info.env" ]; then
                source "${ARTIFACT_DIR}/git-info.env"
                FINAL_IMAGE_TAG="${GIT_COMMIT_HASH}"
            else
                FINAL_IMAGE_TAG="{{DEFAULT_IMAGE_TAG}}"
            fi
        fi
        FULL_IMAGE_NAME="${FINAL_REGISTRY}/${FINAL_REGISTRY_NAMESPACE}/${FINAL_DB_INIT_IMAGE_NAME}:${FINAL_IMAGE_TAG}"
    fi
    
    echo "Pushing DB Init image: ${FULL_IMAGE_NAME}"
    
    # Push image and verify (check for digest in output)
    if docker push "${FULL_IMAGE_NAME}" 2>&1 | grep -q "digest:"; then
        echo "Push successful: ${FULL_IMAGE_NAME}"
    else
        echo "Warning: Could not verify push, but docker push completed"
    fi
    
    # Update artifact file with final image info
    {
        echo "IMAGE_REGISTRY=${FINAL_REGISTRY}"
        echo "IMAGE_NAMESPACE=${FINAL_REGISTRY_NAMESPACE}"
        echo "IMAGE_NAME=${FINAL_DB_INIT_IMAGE_NAME}"
        echo "IMAGE_TAG=${FINAL_IMAGE_TAG}"
        echo "FULL_IMAGE_NAME=${FULL_IMAGE_NAME}"
    } > "${ARTIFACT_DIR}/image-info.env"
    
    echo "Image info saved to artifact file"

# -----------------------------
# Deploy: Deploy database initialization job using Helm
# -----------------------------
deploy K8S_NAMESPACE='' RELEASE_DB_INIT='' HELM_CHART_DB_INIT='' KUBECONFIG_PATH='' WORK_DIR='' IMAGE_TAG='':
    #!/usr/bin/env bash
    set -e
    
    # Priority: provided args (if not empty) > environment variables > defaults
    if [ -n "$K8S_NAMESPACE" ]; then
        FINAL_K8S_NAMESPACE="$K8S_NAMESPACE"
    else
        FINAL_K8S_NAMESPACE="${K8S_NAMESPACE:-{{DEFAULT_K8S_NAMESPACE}}}"
    fi
    
    if [ -n "$RELEASE_DB_INIT" ]; then
        FINAL_RELEASE_DB_INIT="$RELEASE_DB_INIT"
    else
        FINAL_RELEASE_DB_INIT="${RELEASE_DB_INIT:-{{DEFAULT_RELEASE_DB_INIT}}}"
    fi
    
    if [ -n "$HELM_CHART_DB_INIT" ]; then
        FINAL_HELM_CHART_DB_INIT="$HELM_CHART_DB_INIT"
    else
        FINAL_HELM_CHART_DB_INIT="${HELM_CHART_DB_INIT:-{{DEFAULT_HELM_CHART_DB_INIT}}}"
    fi
    
    if [ -n "$KUBECONFIG_PATH" ]; then
        FINAL_KUBECONFIG_PATH="$KUBECONFIG_PATH"
    else
        FINAL_KUBECONFIG_PATH="${KUBECONFIG_PATH:-{{DEFAULT_KUBECONFIG_PATH}}}"
    fi
    
    if [ -n "$WORK_DIR" ]; then
        FINAL_WORK_DIR="$WORK_DIR"
    else
        FINAL_WORK_DIR="${WORK_DIR:-{{DEFAULT_WORK_DIR}}}"
    fi
    
    # Expand ~ in kubeconfig path
    FINAL_KUBECONFIG_PATH="${FINAL_KUBECONFIG_PATH/#\~/$HOME}"
    
    # Convert chart path to absolute if relative
    # Find project root (directory containing helm/ directory)
    if [[ ! "$FINAL_HELM_CHART_DB_INIT" = /* ]]; then
        PROJECT_ROOT="$(pwd)"
        while [ ! -d "${PROJECT_ROOT}/helm" ] && [ "${PROJECT_ROOT}" != "/" ]; do
            PROJECT_ROOT="$(dirname "${PROJECT_ROOT}")"
        done
        if [ -d "${PROJECT_ROOT}/helm" ]; then
            # Extract the chart name from the relative path
            # Examples: "../../helm/db-init" -> "helm/db-init", "helm/db-init" -> "helm/db-init"
            CHART_NAME=$(echo "${FINAL_HELM_CHART_DB_INIT}" | sed -E 's|^\.\./\.\./||' | sed -E 's|^\.\./||' | sed -E 's|^\./||')
            FINAL_HELM_CHART_DB_INIT="${PROJECT_ROOT}/${CHART_NAME}"
        else
            echo "Error: Could not find project root (directory containing helm/)"
            exit 1
        fi
    fi
    
    # Validate chart path exists
    if [ ! -d "${FINAL_HELM_CHART_DB_INIT}" ]; then
        echo "Error: Helm chart not found at ${FINAL_HELM_CHART_DB_INIT}"
        exit 1
    fi
    
    # Convert to absolute path for artifact file
    FINAL_WORK_DIR_ABS=$(cd "${FINAL_WORK_DIR}" && pwd)
    ARTIFACT_DIR="${FINAL_WORK_DIR_ABS}/.artifacts"
    
    # Load image info from artifact file (from push)
    if [ -f "${ARTIFACT_DIR}/image-info.env" ]; then
        source "${ARTIFACT_DIR}/image-info.env"
        echo "Loaded image info from artifact file"
        FINAL_IMAGE_TAG="${IMAGE_TAG}"
        FINAL_IMAGE_REGISTRY="${IMAGE_REGISTRY}"
        FINAL_IMAGE_NAMESPACE="${IMAGE_NAMESPACE}"
        FINAL_IMAGE_NAME="${IMAGE_NAME}"
        FINAL_FULL_IMAGE_NAME="${FULL_IMAGE_NAME}"
    else
        # Fallback: use provided parameters or defaults
        if [ -n "$IMAGE_TAG" ]; then
            FINAL_IMAGE_TAG="$IMAGE_TAG"
        else
            FINAL_IMAGE_TAG="{{DEFAULT_IMAGE_TAG}}"
        fi
        FINAL_IMAGE_REGISTRY="{{DEFAULT_REGISTRY}}"
        FINAL_IMAGE_NAMESPACE="{{DEFAULT_REGISTRY_NAMESPACE}}"
        FINAL_IMAGE_NAME="{{DEFAULT_DB_INIT_IMAGE_NAME}}"
        FINAL_FULL_IMAGE_NAME="${FINAL_IMAGE_REGISTRY}/${FINAL_IMAGE_NAMESPACE}/${FINAL_IMAGE_NAME}:${FINAL_IMAGE_TAG}"
        echo "Warning: No image artifact file found at ${ARTIFACT_DIR}/image-info.env"
        echo "Using default image: ${FINAL_FULL_IMAGE_NAME}"
    fi
    
    # Validate image tag is not empty
    if [ -z "${FINAL_IMAGE_TAG}" ]; then
        echo "Error: IMAGE_TAG is empty. Cannot deploy."
        exit 1
    fi
    
    echo "Deploying DB Init job..."
    echo "  Namespace: ${FINAL_K8S_NAMESPACE}"
    echo "  Release: ${FINAL_RELEASE_DB_INIT}"
    echo "  Chart: ${FINAL_HELM_CHART_DB_INIT}"
    echo "  Image: ${FINAL_FULL_IMAGE_NAME}"
    echo "  Kubeconfig: ${FINAL_KUBECONFIG_PATH}"
    
    # Deploy using Helm with image override (Helm will create namespace if needed)
    KUBECONFIG="${FINAL_KUBECONFIG_PATH}" helm upgrade --install "${FINAL_RELEASE_DB_INIT}" "${FINAL_HELM_CHART_DB_INIT}" \
        --namespace "${FINAL_K8S_NAMESPACE}" \
        --create-namespace \
        --set "image.repository=${FINAL_IMAGE_REGISTRY}/${FINAL_IMAGE_NAMESPACE}/${FINAL_IMAGE_NAME}" \
        --set "image.tag=${FINAL_IMAGE_TAG}" \
        --wait \
        --timeout 5m
    
    echo "DB Init deployment complete"
    echo "Image deployed: ${FINAL_FULL_IMAGE_NAME}"

# -----------------------------
# All: Complete DB Init CI/CD pipeline
# -----------------------------
all BACKEND_REPO='' BACKEND_REF='' WORK_DIR='' REGISTRY='' REGISTRY_NAMESPACE='' DB_INIT_IMAGE_NAME='' IMAGE_TAG='' K8S_NAMESPACE='' RELEASE_DB_INIT='' HELM_CHART_DB_INIT='' KUBECONFIG_PATH='':
    #!/usr/bin/env bash
    set -e
    
    # Find the justfile path by searching for deploy/db-init/justfile
    # Start from current directory and go up until we find it
    CURRENT_DIR="$(pwd)"
    JUSTFILE_PATH=""
    SEARCH_DIR="${CURRENT_DIR}"
    
    while [ "${SEARCH_DIR}" != "/" ]; do
        if [ -f "${SEARCH_DIR}/deploy/db-init/justfile" ]; then
            JUSTFILE_PATH="${SEARCH_DIR}/deploy/db-init/justfile"
            break
        fi
        SEARCH_DIR="$(dirname "${SEARCH_DIR}")"
    done
    
    # If not found, try relative path from current directory
    if [ -z "${JUSTFILE_PATH}" ] && [ -f "deploy/db-init/justfile" ]; then
        JUSTFILE_PATH="$(cd deploy/db-init && pwd)/justfile"
    fi
    
    # If still not found, use current directory
    if [ -z "${JUSTFILE_PATH}" ]; then
        JUSTFILE_PATH="deploy/db-init/justfile"
    fi
    
    echo "=========================================="
    echo "Starting DB Init CI/CD pipeline"
    echo "=========================================="
    
    # Step 1: Clone
    just --justfile "${JUSTFILE_PATH}" clone BACKEND_REPO="$BACKEND_REPO" BACKEND_REF="$BACKEND_REF" WORK_DIR="$WORK_DIR"
    
    # Step 2: Build DB Init image
    just --justfile "${JUSTFILE_PATH}" build REGISTRY="$REGISTRY" REGISTRY_NAMESPACE="$REGISTRY_NAMESPACE" DB_INIT_IMAGE_NAME="$DB_INIT_IMAGE_NAME" IMAGE_TAG="$IMAGE_TAG" WORK_DIR="$WORK_DIR"
    
    # Step 3: Push DB Init image
    just --justfile "${JUSTFILE_PATH}" push REGISTRY="$REGISTRY" REGISTRY_NAMESPACE="$REGISTRY_NAMESPACE" DB_INIT_IMAGE_NAME="$DB_INIT_IMAGE_NAME" IMAGE_TAG="$IMAGE_TAG" WORK_DIR="$WORK_DIR"
    
    # Step 4: Deploy DB Init job
    just --justfile "${JUSTFILE_PATH}" deploy K8S_NAMESPACE="$K8S_NAMESPACE" RELEASE_DB_INIT="$RELEASE_DB_INIT" HELM_CHART_DB_INIT="$HELM_CHART_DB_INIT" KUBECONFIG_PATH="$KUBECONFIG_PATH" WORK_DIR="$WORK_DIR" IMAGE_TAG="$IMAGE_TAG"
    
    echo "=========================================="
    echo "DB Init CI/CD pipeline completed"
    echo "=========================================="

# -----------------------------
# Clean: Remove work directory, artifacts, and optionally Docker images
# -----------------------------
clean WORK_DIR='' REGISTRY='' REGISTRY_NAMESPACE='' DB_INIT_IMAGE_NAME='' CLEAN_IMAGES='false':
    #!/usr/bin/env bash
    set -e
    
    if [ -n "$WORK_DIR" ]; then
        FINAL_WORK_DIR="$WORK_DIR"
    else
        FINAL_WORK_DIR="${WORK_DIR:-{{DEFAULT_WORK_DIR}}}"
    fi
    
    if [ -n "$REGISTRY" ]; then
        FINAL_REGISTRY="$REGISTRY"
    else
        FINAL_REGISTRY="${REGISTRY:-{{DEFAULT_REGISTRY}}}"
    fi
    
    if [ -n "$REGISTRY_NAMESPACE" ]; then
        FINAL_REGISTRY_NAMESPACE="$REGISTRY_NAMESPACE"
    else
        FINAL_REGISTRY_NAMESPACE="${REGISTRY_NAMESPACE:-{{DEFAULT_REGISTRY_NAMESPACE}}}"
    fi
    
    if [ -n "$DB_INIT_IMAGE_NAME" ]; then
        FINAL_DB_INIT_IMAGE_NAME="$DB_INIT_IMAGE_NAME"
    else
        FINAL_DB_INIT_IMAGE_NAME="${DB_INIT_IMAGE_NAME:-{{DEFAULT_DB_INIT_IMAGE_NAME}}}"
    fi
    
    # Clean work directory
    if [ -d "${FINAL_WORK_DIR}" ]; then
        echo "Removing work directory: ${FINAL_WORK_DIR}"
        rm -rf "${FINAL_WORK_DIR}"
        echo "Work directory removed"
    else
        echo "Work directory does not exist: ${FINAL_WORK_DIR}"
    fi
    
    # Clean local Docker images if requested
    if [ "${CLEAN_IMAGES}" = "true" ] || [ "${CLEAN_IMAGES}" = "1" ]; then
        echo "Cleaning local Docker images..."
        IMAGE_PATTERN="${FINAL_REGISTRY}/${FINAL_REGISTRY_NAMESPACE}/${FINAL_DB_INIT_IMAGE_NAME}"
        # Find and remove matching images
        # Use docker images output and parse with awk to avoid justfile variable syntax conflicts
        docker images "${IMAGE_PATTERN}" 2>/dev/null | awk 'NR>1 {print $1":"$2}' | while read -r img; do
            if [ -n "${img}" ] && [ "${img}" != "REPOSITORY:TAG" ]; then
                echo "  Removing image: ${img}"
                docker rmi "${img}" 2>/dev/null || true
            fi
        done
        echo "Docker images cleaned"
    fi
    
    echo "Clean complete"

